package org.zn.note.designpattern;

/**
 * Model-View-Controller（模型-视图-控制器）
 * Model（模型） - 模型代表一个存取数据的对象或 JAVA POJO。它也可以带有逻辑，在数据变化时更新控制器。
 * View（视图） - 视图代表模型包含的数据的可视化。
 * Controller（控制器） - 控制器作用于模型和视图上。它控制数据流向模型对象，并在数据变化时更新视图。它使视图与模型分离开。
 * <p>
 * View 专注于展示
 * Model 是数据（具体这个数据从哪来的不关心）
 * Controller 是两者的桥梁，可以是将Model给View来展示，也可以使View上提出请求来改变Model
 * （MVC中，数据到Model就结束了，具体工程中有Service处理业务逻辑、Repository数据库层都不在MVC中）
 */
public class Pattern26_MVC {

    public static void main(String[] args) {
        //从数据库获取学生记录
        Student model = retrieveStudentFromDatabase();
        //创建一个视图：把学生详细信息输出到控制台
        StudentView view = new StudentView();
        StudentController controller = new StudentController(model, view);
        controller.updateView();
        //更新模型数据
        controller.setStudentName("John");
        controller.updateView();
    }

    // 从数据库查出Student信息
    private static Student retrieveStudentFromDatabase() {
        Student student = new Student();
        student.setName("Robert");
        student.setRollNo("10");
        return student;
    }

    // Model
    private static class Student {
        private String rollNo;
        private String name;

        public String getRollNo() {
            return rollNo;
        }

        public void setRollNo(String rollNo) {
            this.rollNo = rollNo;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

    // View (一般是网页，比如JSP之类的)
    private static class StudentView {
        void printStudentDetails(String studentName, String studentRollNo) {
            System.out.println("Student: ");
            System.out.println("Name: " + studentName);
            System.out.println("Roll No: " + studentRollNo);
        }
    }

    // Controller
    private static class StudentController {
        private Student model;
        private StudentView view;

        public StudentController(Student model, StudentView view) {
            this.model = model;
            this.view = view;
        }

        public void setStudentName(String name) {
            model.setName(name);
        }

        public String getStudentName() {
            return model.getName();
        }

        public void setStudentRollNo(String rollNo) {
            model.setRollNo(rollNo);
        }

        public String getStudentRollNo() {
            return model.getRollNo();
        }

        public void updateView() {
            view.printStudentDetails(model.getName(), model.getRollNo());
        }
    }
}
